home *** CD-ROM | disk | FTP | other *** search
/ Aminet 31 / Aminet 31 (1999)(Schatztruhe)[!][Jun 1999].iso / Aminet / dev / gui / gui4cli.lha / Gui4Cli / Ext / LVFormat / rewrap.h < prev    next >
Text File  |  1999-04-21  |  8KB  |  287 lines

  1.  
  2. // ==============================================================
  3. // Rewrap a listview
  4. // - construct a new list with the line lengths wanted and
  5. //   replace & kill the old one.
  6. // gcm    = struct *GCmain (from where we get the lv pointer)
  7. // length = the new line length wanted
  8. // hdchars = the chars which will be considered as header
  9. // justmode = 1=justify, 2=unjustijy, 3=center, 0=leave alone
  10. // ==============================================================
  11.  
  12. rewrap (    struct GCmain *gcm, LONG length, UBYTE *hdchars, SHORT justmode,
  13.             struct ExecBase *SysBase, struct DosLibrary *DOSBase)
  14. {
  15.     LONG   lh=0, c=0, lastc=0;
  16.     struct List   *ls, *lst;
  17.     struct fulist *fls;
  18.     struct lister *fl, *nextfl;
  19.     UBYTE  *buff, *p, *b, *lastp, *lastb;
  20.     UBYTE  *head, *h, *jbf;
  21.     BOOL   just=0, unjust=0, center=0, reset=0, flag=0;
  22.  
  23.     // get pointer to current listview
  24.     if (!(fls = gcm->curlv) || !fls->ls || IsListEmpty(fls->ls)) 
  25.         return (0);
  26.     
  27.     // get working buffers, check they're long enough
  28.     if (gcm->buffsize < (length - 2)) return (0);
  29.     buff = gcm->membuff[0];
  30.     head = gcm->membuff[1]; // for line header
  31.     jbf  = gcm->membuff[2]; // for justification
  32.  
  33.     // set justify flags
  34.     if      (justmode == 1) { just=1; unjust=1; }
  35.     else if (justmode == 2) unjust=1;
  36.     else if (justmode == 3) { center=1; unjust=1; } 
  37.     else if (justmode == 4) { reset=1; unjust=1; }
  38.  
  39.     // prepare a new list struct
  40.     if (!(lst = getlist(SysBase, DOSBase))) return (0);
  41.  
  42.     // unattach old list - attach new
  43.     ls = fls->ls; fls->ls = lst;
  44.     fls->maxlength = fls->maxnow = fls->totnum = 0;
  45.     fls->curpt = NULL; fls->line  = -1;
  46.  
  47.     fl = (struct lister *)(ls->lh_Head); // point to 1st rec
  48.  
  49.     // skip any blank lines at beginning
  50.     while ((nextfl = (struct lister *)(fl->node.ln_Succ)) && !flag)
  51.     {    if (fl->start[0] == '\0')
  52.        {     addline (fls, "", 0, SysBase, DOSBase);
  53.             fl = nextfl;
  54.        }
  55.        else flag = 1;
  56.     }
  57.  
  58.     // get 1st leading indent
  59.     p = lastp = fl->start;
  60.     for     (lh=0, h=head; 
  61.             (lh<length) && *p && ((*p==' ') || isin(*p, hdchars)); 
  62.             ++p, ++h, ++lh)
  63.             *h = *p;
  64.     *h = '\0';
  65.  
  66.     if (reset)  
  67.     {    c=0;  *buff='\0';  
  68.         b=lastb=buff;   
  69.     }
  70.  
  71.     else
  72.     {    c=lh; strcpy (buff, head);
  73.         b = lastb = &buff[lh];
  74.     }
  75.  
  76.     // do the whole list..
  77.     while (nextfl = (struct lister *)(fl->node.ln_Succ))
  78.     {
  79.        while (*p)
  80.        {
  81.          // mark last space or line breakable char encountered
  82.          if (*p==' ')
  83.           {
  84.                  if (unjust)  // delete spaces if unjust on
  85.                {  while (p[1]==' ') ++p;
  86.                   if (b==buff) ++p; // if at the start of a line..
  87.                }
  88.                lastp = p;
  89.              lastb = b;
  90.              lastc = c;
  91.             }
  92.  
  93.           // copy char
  94.           *b = *p;
  95.           ++b; ++p; ++c;
  96.            
  97.           // if we're over the length, change line..
  98.           if (c >= length)
  99.           {
  100.               if (lastb == &buff[lh])   // line unbroken - force break
  101.              {  lastp = p;
  102.                     lastc = c;
  103.                 lastb = b;
  104.              }
  105.              else p = lastp;
  106.               
  107.                while (*p==' ') ++p;
  108.                *lastb = '\0';
  109.  
  110.                // if justify is on..
  111.                if (just)
  112.                {  c = justify (buff, &buff[lh], jbf, length, SysBase, DOSBase);
  113.                   addline (fls, jbf, c, SysBase, DOSBase);
  114.                   }
  115.  
  116.                else if (center)
  117.                {  c = centertxt (buff, &buff[lh], jbf, length, SysBase, DOSBase);
  118.                      addline (fls, jbf, c, SysBase, DOSBase);
  119.                }
  120.  
  121.                else addline (fls, buff, lastc, SysBase, DOSBase);
  122.  
  123.                // reinitiate line head buffer
  124.                if (reset)
  125.                {    c=0; *buff='\0'; 
  126.                     b=lastb=buff; 
  127.                 }
  128.                else
  129.                {  strcpy (buff, head);
  130.                   b = lastb = &buff[lh];
  131.                   c = lh;
  132.                }
  133.  
  134.             }    // end of new line handling
  135.        }        // end of while (*p)
  136.  
  137.        if (!nextfl->node.ln_Succ)               // end of file
  138.        {
  139.            *b = '\0';
  140.           if (center)
  141.           {    c = centertxt (buff, &buff[lh], jbf, length, SysBase, DOSBase);
  142.                   addline (fls, jbf, c, SysBase, DOSBase);
  143.           }
  144.           else addline (fls, buff, c, SysBase, DOSBase);
  145.           goto endwrap;
  146.        }
  147.  
  148.        else if (nextfl->start[0] == '\0')       // a paragraph..
  149.        {
  150.           *b = '\0';
  151.           if (center)
  152.           {    c = centertxt (buff, &buff[lh], jbf, length, SysBase, DOSBase);
  153.                   addline (fls, jbf, c, SysBase, DOSBase);
  154.           }
  155.           else addline (fls, buff, c, SysBase, DOSBase);
  156.  
  157.           fl = nextfl;
  158.           nextfl = (struct lister *)(fl->node.ln_Succ);
  159.           // add a blank line
  160.           addline (fls, "", 0, SysBase, DOSBase);
  161.           // goto next line..
  162.           fl = nextfl;
  163.  
  164.           // reinitiate head buffer
  165.           p = lastp = fl->start;
  166.           for (lh=0, h=head; (lh<length) && *p && ((*p==' ') || isin(*p, hdchars)); ++p, ++h, ++lh)
  167.               *h = *p;
  168.           *h = '\0';
  169.           if (reset)  
  170.           {  c=0;  *buff='\0';  
  171.                 b=lastb=buff;
  172.            }
  173.           else
  174.           {    c=lh; strcpy (buff, head);
  175.              b = lastb = &buff[lh];
  176.           }
  177.         }
  178.        // otherwise skip it
  179.        else 
  180.        {  fl = nextfl;
  181.           // reinitiate head buffer
  182.           p = lastp = fl->start;
  183.           for (lh=0, h=head; (lh<length) && *p && ((*p==' ') || isin(*p, hdchars)); p++, h++, lh++)
  184.               *h = *p;
  185.           *h = '\0';
  186.           *b = ' ';     // insert a space at line end
  187.           lastb = b;
  188.           lastc = c;
  189.            ++b; ++c; 
  190.        }
  191.  
  192.     }  // end of main while loop
  193.  
  194.     endwrap:
  195.     // our new list is ready - free the old one
  196.     freelist (ls, SysBase, DOSBase);
  197.  
  198.     return (1); // ok..
  199. }
  200.  
  201. // ==============================================================
  202. //    do justify
  203. //    Justify *str into *buff which should become length long
  204. //    hdrend is the end of the line header
  205. // ==============================================================
  206. LONG justify (UBYTE *str, UBYTE *hdrend, UBYTE *buff, LONG length,
  207.           struct ExecBase *SysBase, struct DosLibrary *DOSBase)
  208. {
  209.    LONG spaces, len=0, add=0, fill, c, step=0, stepcount=0, bal=0;
  210.    UBYTE *p, *buffstart;
  211.    buffstart = buff;
  212.  
  213.    // count spaces in str & it's length
  214.    for (p=str; *p && (p < hdrend); ++p, ++len); // go past header
  215.    for (spaces=0; *p; ++p, ++len) if (*p==' ') ++spaces;
  216.  
  217.    // the number of characters we have to add
  218.    fill = length - len;
  219.    if (spaces) 
  220.    {  // num of spaces to add to each space (probably 0)
  221.       add = fill / spaces;
  222.       // also add a space every <step> chars
  223.       bal = fill - (spaces * add); // how many chars left
  224.       if (bal)
  225.          step = spaces / bal;  // add space every step chars
  226.    }
  227.  
  228.    while (*str)
  229.    {   if ((*str == ' ') && (str > hdrend))
  230.        {
  231.           *buff = ' ';
  232.           ++buff;
  233.           for (c=0; c<add; ++c) {  *buff=' '; ++buff; }
  234.           ++stepcount;
  235.           if ((stepcount == step) && bal)
  236.           {  *buff=' '; ++buff;
  237.              stepcount = 0;
  238.              --bal;
  239.           }
  240.        }
  241.        else 
  242.        {  *buff=*str; 
  243.           ++buff;
  244.        }
  245.        ++str;
  246.    }
  247.    *buff = '\0';
  248.    return ((LONG)(buff - buffstart));
  249. }
  250.  
  251.  
  252. // ==============================================================
  253. //    Center text
  254. //    Center *str into *buff for a line length long
  255. //    hdrend is the end of the line header
  256. // ==============================================================
  257. LONG centertxt (UBYTE *str, UBYTE *hdrend, UBYTE *buff, LONG length,
  258.                      struct ExecBase *SysBase, struct DosLibrary *DOSBase)
  259. {
  260.    LONG  linelen, actlen, addlen, hdrlen;
  261.    UBYTE *p, *b;
  262.  
  263.    hdrlen = (LONG)(hdrend - str);
  264.    linelen = length - hdrlen;
  265.    actlen  = strlen(str) - hdrlen;
  266.    addlen  = (linelen - actlen) / 2; // the No of spaces to be added each side
  267.  
  268.    b = buff;
  269.    while (str < hdrend)    // copy header
  270.    {   *b = *str;
  271.        ++b; ++str;
  272.    }
  273.    while (addlen)          // copy left spaces
  274.    {   *b=' ';  ++b;
  275.        --addlen;
  276.    }
  277.    while (*str)            // copy the text
  278.    {   *b = *str;
  279.        ++b; ++str;
  280.    }
  281.    *b = '\0';
  282.    return ((LONG)(b - buff));
  283. }
  284.  
  285.  
  286.  
  287.